/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jackal;

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;

/**
 * Основной класс, осблуживающий работу с пользователем
 * 
 * @author andrej
 */
public class Jackal extends javax.swing.JFrame {
    private World world; 
    private GuiJFrame islandFrame;
    private EnemyLogic enemyLogic1 = new EnemyLogic(EnemyLevel.LEVEL_EASY);
    private EnemyLogic enemyLogic2 = new EnemyLogic(EnemyLevel.LEVEL_EASY);
    
    static final Border SOLID_GREEN_BORDER = BorderFactory.createLineBorder(Color.GREEN, 1);
   
    Component checkedComponent = null;
    
    
    /**
     * 
     */
    public Jackal() {
        initComponents();
        
        Gamer gamer1 = new Gamer(new Point(6, 0), 1); // первый игрок начинает вверху экрана 
        //gamer1.pirate1.setName("Пират 1");
        Gamer gamer2 = new Gamer(new Point(6, 12), 2); // второй игрок начинает внизу экрана 
        //gamer2.pirate1.setName("Пират 2");

        createPopupMenu();
        addPopupMenu(gamer1.pirate1);
        addPopupMenu(gamer1.pirate2);
 
        //island = new Island(); 
        world = new World(new Island(), gamer1, gamer2);
        
        islandFrame = new GuiJFrame(world);
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jButton1 = new javax.swing.JButton();
        jPanel1 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jButton2 = new javax.swing.JButton();
        jButton3 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jButton1.setText("jButton1");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 0, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 602, Short.MAX_VALUE)
        );

        jLabel1.setText("jLabel1");

        jButton2.setText("jButton2");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });

        jButton3.setText("T");
        jButton3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton3ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jButton1)
                        .addGap(18, 18, 18)
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jButton3, javax.swing.GroupLayout.PREFERRED_SIZE, 48, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(0, 11, Short.MAX_VALUE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(7, 7, 7)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButton1)
                    .addComponent(jLabel1)
                    .addComponent(jButton2)
                    .addComponent(jButton3))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGap(15, 15, 15))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void setMouseMovedListener(Component comp){
        comp.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            @Override
            public void mouseMoved(java.awt.event.MouseEvent evt) {
                //jLabelMouseMoved(evt);
            }
         });
    } 
    private void setMouseClickedListener(Component comp){
        comp.addMouseListener(new java.awt.event.MouseAdapter() {
            @Override
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jLabelMouseClicked(evt);
            }
        });
    } 

    private JPopupMenu popup;
    private Gamer.Pirate checkedPirate = null;
    
    // An inner class to check whether mouse events are the popup trigger
    class MousePopupListener extends MouseAdapter {
        @Override
        public void mousePressed(MouseEvent e) { checkPopup(e); }
        @Override
        public void mouseClicked(MouseEvent e) { checkPopup(e); }
        @Override
        public void mouseReleased(MouseEvent e) { checkPopup(e); }
        private void checkPopup(MouseEvent e) {
            if (e.isPopupTrigger()) {
                checkedPirate = (Gamer.Pirate) e.getComponent();
                if (checkedPirate.haveMoney) {
                    popup.getComponent(0).setVisible(true);
                } else {
                    popup.getComponent(0).setVisible(false);
                }
                popup.show(e.getComponent(), e.getX(), e.getY());
            }
        }
    }
    
    private void createPopupMenu() {
        popup = new JPopupMenu();
        ActionListener menuListener = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                piratePopupActionPerformed(event);
            }
        };

        JMenuItem itemMoney = new JMenuItem("Бросить монету");
        itemMoney.addActionListener(menuListener);
        itemMoney.setActionCommand("dropMoney");
        popup.add(itemMoney);

        //popup.addSeparator();

        JMenuItem itemHelp = new JMenuItem("Обо мне");
        itemHelp.addActionListener(menuListener);
        itemHelp.setActionCommand("help");
        popup.add(itemHelp);

        //popup.setLabel("Justification");
        //popup.setBorder(new BevelBorder(BevelBorder.RAISED));
    }
    private void addPopupMenu(Gamer.Pirate pirate) {
        pirate.addMouseListener(new MousePopupListener());
    }
    
    public void piratePopupActionPerformed(ActionEvent event) {
        if (event.getActionCommand().equals("dropMoney")) {
            checkedPirate.dropMoney();
            System.out.println(checkedPirate.getName());
            islandFrame.displayAllObjects(world);
        } 
    }

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        islandFrame.initGamers(world.gamer1);
        islandFrame.initGamers(world.gamer2);
        
        for (int i=0; i<Island.BOARD_SIZE; i++){
            for (int j=0; j<Island.BOARD_SIZE; j++){
                setMouseMovedListener(world.island.getPlace(i, j));
                setMouseClickedListener(world.island.getPlace(i, j));
            }
        }
        
        setMouseMovedListener(world.gamer1.boat);
        setMouseClickedListener(world.gamer1.boat);

        setMouseMovedListener(world.gamer1.pirate1);
        setMouseClickedListener(world.gamer1.pirate1);

        setMouseMovedListener(world.gamer1.pirate2);
        setMouseClickedListener(world.gamer1.pirate2);

        //setMouseMovedListener(gamer2.pirate1); // надо отключить после отладки
        //setMouseClickedListener(gamer2.pirate1); //

        islandFrame.displayAllObjects(world);
    }//GEN-LAST:event_jButton1ActionPerformed

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
        //enemyLogic.enemyPirateMove(gamer2.pirate1, world);
        enemyLogic1.move(world.gamer2, world);

        islandFrame.displayAllObjects(world);

        isGameOver(world);
    }//GEN-LAST:event_jButton2ActionPerformed

    private boolean isGameOver(World world) {
        if (world.isGameOver()) {

            if (world.gamer1.boat.moneyCount > world.gamer2.boat.moneyCount) {
                JOptionPane.showMessageDialog(null, "Поздравляем! Вы победили! Со счетом "+
                    world.gamer1.boat.moneyCount+":"+world.gamer2.boat.moneyCount,
                "ПОБЕДА", 1);
            } else if (world.gamer1.boat.moneyCount < world.gamer2.boat.moneyCount) {
                JOptionPane.showMessageDialog(null, "Вот незадача, противник опередил вас! Счет игры "+
                    world.gamer1.boat.moneyCount+":"+world.gamer2.boat.moneyCount,
                "Проигрыш", 0);
            }
            
            //System.out.println("Игра завершена");
            return true;
        }

        islandFrame.setTitle("Счёт: золота у вас "+world.gamer1.boat.moneyCount+
                ", у противника "+world.gamer2.boat.moneyCount);
        return false;
    }
    
    private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed
        JackalTest jackalTest = new JackalTest(world, islandFrame);
        
        jackalTest.dummyVersusDummy(); 
    }//GEN-LAST:event_jButton3ActionPerformed

    private void jLabelMouseClicked(java.awt.event.MouseEvent evt) { 
        islandFrame.setNullBorder(); // убираем границы со всех Label 

        if (((BasicObj) evt.getComponent()).getType() == BasicObj.PIRATE) {
            for (int i=0; i<Island.BOARD_SIZE; i++) {
                for (int j=0; j<Island.BOARD_SIZE; j++) {
                    if ( ((Gamer.Pirate) evt.getComponent()).canMoveTo(world.island.getPlace(i, j)) ) {
                        world.island.getPlace(i, j).setBorder(SOLID_GREEN_BORDER);   
                    }
                }
            }
        } //else island.places[i][j].setBorder(null);
                        
        if (((BasicObj) evt.getComponent()).getType() == BasicObj.BOAT) {
            for (int i=0; i<Island.BOARD_SIZE; i++) {
                for (int j=0; j<Island.BOARD_SIZE; j++) {
                    if ( ((Gamer.Boat) evt.getComponent()).canMoveTo(world.island.getPlace(i, j)) ) {
                        world.island.getPlace(i, j).setBorder(SOLID_GREEN_BORDER);
                    }
                }
            }
        } //else island.places[i][j].setBorder(null);
        

        //System.out.print(checkedComponent.hashCode());
        if (checkedComponent != null && checkedComponent.hashCode() != evt.getComponent().hashCode()) {
            if (((BasicObj) checkedComponent).getType() == BasicObj.PIRATE &&
                    Island.getDistanceFromTo(((BasicObj) checkedComponent).getCoord(),
                    ((BasicObj) evt.getComponent()).getCoord()) == 1) {
                boolean isMoved = ((Gamer.Pirate) checkedComponent).moveTo(((BasicObj) evt.getComponent()).getCoord(), world);
                if (isMoved) {
                    jButton2ActionPerformed(null);
                }
            }
            
            if (((BasicObj) checkedComponent).getType() == BasicObj.BOAT &&
                    Island.getDistanceFromTo(((BasicObj) checkedComponent).getCoord(),
                    ((BasicObj) evt.getComponent()).getCoord()) == 1) {
                boolean isMoved = ((Gamer.Boat) checkedComponent).moveTo(((BasicObj) evt.getComponent()).getCoord(), world);
                if (isMoved) {
                    jButton2ActionPerformed(null);
                }
            }
        }

        if (checkedComponent != null && ((BasicObj) checkedComponent).getType() == BasicObj.PIRATE) {
            while ( ! ((Gamer.Pirate) checkedComponent).way.isEmpty()) {
                //System.out.println(">>>>>>>>>>> Вот он путь");
                //((Gamer.Pirate) checkedComponent).moveTo(((Gamer.Pirate) checkedComponent).way.get(0), world);
                jButton2ActionPerformed(null);

                ((Gamer.Pirate) checkedComponent).goNextWayPoint(world);
                //((Gamer.Pirate) checkedComponent).way.remove(0);
                islandFrame.displayAllObjects(world);
                isGameOver(world);
            }
        }

        checkedComponent = evt.getComponent();
        
        if (((BasicObj) evt.getComponent()).getType() == BasicObj.PIRATE ||
                ((BasicObj) evt.getComponent()).getType() == BasicObj.BOAT) {
            ((JLabel) evt.getComponent()).setBorder(SOLID_GREEN_BORDER);
        }
        
        islandFrame.displayAllObjects(world);
        
        isGameOver(world);
    }
    

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(Jackal.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(Jackal.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(Jackal.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(Jackal.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Jackal().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JPanel jPanel1;
    // End of variables declaration//GEN-END:variables
}
